<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\AffiliateLog;
use App\Models\BusinessSetting;
use App\Models\RefundRequest;
use App\Models\OrderDetail;
use App\Models\Seller;
use App\Models\Wallet;
use App\Models\User;
use App\Models\Order;
use Artisan;
use Auth;

class RefundRequestController extends Controller
{
    /**
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */

    //Store Customer Refund Request
    public function request_store(Request $request, $id)
    {
        $order_detail = OrderDetail::where('id', $id)->first();
        $refund = new RefundRequest;
        $refund->user_id = Auth::user()->id;
        $refund->order_id = $order_detail->order_id;
        $refund->order_detail_id = $order_detail->id;
        $refund->seller_id = $order_detail->seller_id;
        $refund->seller_approval = 0;
        $refund->reason = $request->reason;
        $refund->admin_approval = 0;
        $refund->admin_seen = 0;
        $refund->refund_amount = $order_detail->price + $order_detail->tax;
        $refund->refund_status = 0;
        if ($refund->save()) {
            flash( translate("Refund Request has been sent successfully") )->success();
            return redirect()->route('purchase_history.index');
        }
        else {
            flash( translate("Something went wrong") )->error();
            return back();
        }
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function vendor_index()
    {
        $refunds = RefundRequest::where('seller_id', Auth::user()->id)->latest()->paginate(10);
        if (Auth::user()->user_type == 'admin' || Auth::user()->user_type == 'staff') {
            return view('refund_request.frontend.recieved_refund_request.index', compact('refunds'));
        }
        else {
            return view('refund_request.frontend.recieved_refund_request.index', compact('refunds'));
        }
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function customer_index()
    {
        $refunds = RefundRequest::where('user_id', Auth::user()->id)->latest()->paginate(10);
        return view('refund_request.frontend.refund_request.index', compact('refunds'));
    }

    //Set the Refund configuration
    public function refund_config()
    {
        return view('refund_request.config');
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function refund_time_update(Request $request)
    {
        $business_settings = BusinessSetting::where('type', $request->type)->first();
        if ($business_settings != null) {
            $business_settings->value = $request->value;
            $business_settings->save();
        }
        else {
            $business_settings = new BusinessSetting;
            $business_settings->type = $request->type;
            $business_settings->value = $request->value;
            $business_settings->save();
        }
        Artisan::call('cache:clear');
        flash( translate("Refund Request sending time has been updated successfully") )->success();
        return back();
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function refund_sticker_update(Request $request)
    {
        $business_settings = BusinessSetting::where('type', $request->type)->first();
        if ($business_settings != null) {
            $business_settings->value = $request->logo;
            $business_settings->save();
        }
        else {
            $business_settings = new BusinessSetting;
            $business_settings->type = $request->type;
            $business_settings->value = $request->logo;
            $business_settings->save();
        }
        Artisan::call('cache:clear');
        flash( translate("Refund Sticker has been updated successfully"))->success();
        return back();
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function admin_index()
    {
        $refunds = RefundRequest::where('refund_status', 0)->latest()->paginate(15);
        return view('refund_request.index', compact('refunds'));
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function paid_index()
    {
        $refunds = RefundRequest::where('refund_status', 1)->latest()->paginate(15);
        return view('refund_request.paid_refund', compact('refunds'));
    }

    public function rejected_index()
    {
        $refunds = RefundRequest::where('refund_status', 2)->latest()->paginate(15);
        return view('refund_request.rejected_refund', compact('refunds'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function request_approval_vendor(Request $request)
    {
        try {
            \DB::beginTransaction();
            $refund = RefundRequest::when(Auth::user()->user_type === 'seller', function($query) {
                $query->where('seller_id', Auth::user()->id);
            })->findOrFail($request->el);
            if (Auth::user()->user_type == 'admin' || Auth::user()->user_type == 'staff') {
                $refund->seller_approval = 1;
                $refund->admin_approval = 1;
                //$refund->saveOrFail();
            }
            else {
                $refund->seller_approval = 1;
            }
            if (addon_is_activated('affiliate_system') && Auth::user()->user_type == 'seller') {
                
                $affiliateLogs = AffiliateLog::where('order_id', $refund->order_id)->get();
                if ($affiliateLogs->count()) {
                    foreach ($affiliateLogs as $affiliateLog) {
                        $refund_product_id = $refund->orderDetail->product_id;
                        $log_order_detail = \json_decode($affiliateLog->order_detail, true);
                        if (is_array($log_order_detail)) {
                            $key = array_search($refund_product_id, array_column($log_order_detail, 'product_id'));
                            if ($key !== false) {
                                if (!in_array($log_order_detail[$key]['status'], ['refunded', 'refunded_confirmed'])) {
                                    //$amount = \bcmul($log_order_detail[$key]['amount'], $log_order_detail[$key]['num'], 2);
                                    //User::where('id', $refund->seller_id)->increment('balance', $amount);
                                    $log_order_detail[$key]['status'] = 'refunded';
                                    //$affiliateLog->decrement('amount', $amount);
                                    $affiliateLog->order_detail = \json_encode($log_order_detail);
                                    $affiliateLog->saveOrFail();
                                }
                            }
                            //$affiliateLog->
                            $affiliateLog->saveOrFail();
                        }
                        
                        
                        
                    }
                }
                
            }
            $refund->save();
            \DB::commit();
            return 1;
        }catch(\Throwable $ex) {
            \DB::rollBack();
            throw $ex;
        }
        return 0;
    }

    /**
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function refund_pay(Request $request)
    {
        try {
            \DB::beginTransaction();
            $refund = RefundRequest::lockForUpdate()->findOrFail($request->el);

            /*if ($refund->seller_approval == 1) {
                $seller = Seller::where('user_id', $refund->seller_id)->first();
                if ($seller != null) {
                    
                    $order = Order::findOrFail( $refund->order_id );
                 
                    $seller->admin_to_pay -= $order->profit;
                }
                $seller->save();
            }*/
            $wallet = new Wallet;
            $wallet->user_id = $refund->user_id;
            $wallet->amount = $refund->refund_amount;
            $wallet->payment_method = 'Refund';
            $wallet->payment_details = 'Product Money Refund';
            $wallet->save();
            
            /*$wallet = new Wallet;
            $wallet->user_id = $refund->seller_id;
            $wallet->amount = \bcmul($refund->orderDetail->product->purchase_price, $refund->orderDetail->quantity, 2);
            $wallet->payment_method = 'Refund';
            $wallet->payment_details = 'Product Money Refund';
            $wallet->save();*/
            
            //User::where('id', $refund->seller_id)->increment('balance', \bcmul($refund->orderDetail->product->purchase_price, $refund->orderDetail->quantity, 2));
            // $user = User::findOrFail($refund->user_id);
            // $user->balance += $refund->refund_amount;
            // $user->save();
            
            //User::where('id', $refund->user_id)->increment('balance', $refund->refund_amount);
                
                
                
            $refund->order->decrement('grand_total', $refund->refund_amount);
            
            User::where('id', $refund->user_id)->increment('balance', $refund->refund_amount);
            
            
            
            if ($refund->order->pickup_status == 'picked') {
                
                Seller::where('user_id', $refund->seller_id)->decrement('admin_to_pay', $refund->refund_amount);
            
                $refund_picked_money = \bcmul($refund->orderDetail->product->stocks->where('variant', $refund->orderDetail->variantion)->first()->price, $refund->orderDetail->quantity, 2);
                
                
                if ($refund->orderDetail->product->pid > 0) {
                    $referrel_stocks = $refund->orderDetail->product->referrel->stocks->where('variant', $refund->orderDetail->variantion)->first();
                    $refund_picked_money = $referrel_stocks->price * $refund->orderDetail->quantity;
                    
                    User::where('id', $refund->seller_id)->increment('balance', $refund_picked_money);
                    $refund->order->decrement('pickup_amount', $refund_picked_money);
                    
                }
                
                $wallet = new Wallet;
                $wallet->user_id = $refund->seller_id;
                $wallet->amount = $refund_picked_money;
                $wallet->payment_method = 'Refund';
                $wallet->payment_details = 'Product Money Refund';
                $wallet->save();
            
            }
                
            
             if (addon_is_activated('affiliate_system')) {
                $affiliateLogs = AffiliateLog::where('order_id', $refund->order_id)->get();
                if ($affiliateLogs->count()) {
                    foreach ($affiliateLogs as $affiliateLog) {
                        
                        $log_order_detail = \json_decode($affiliateLog->order_detail, true);
                        if (is_array($log_order_detail)) {
                            //$amount = '0.00';
                            foreach ($log_order_detail as $k => $row) {
                                if ($row['status'] === 'refunded') {
                                    $row['status'] = 'refunded_confirmed';
                                    $affiliateLog->decrement('amount',  \bcmul($row['amount'], $row['num'], 2));
                                }
                                $log_order_detail[$k] = $row;
                            }
                            
                            $affiliateLog->order_detail = \json_encode($log_order_detail);
                            $affiliateLog->saveOrFail();
                        }
                    }
                }
             }
            
            if (Auth::user()->user_type == 'admin' || Auth::user()->user_type == 'staff') {
                $refund->admin_approval = 1;
                $refund->refund_status = 1;
            }
            $refund->save();
            \DB::commit();
            return 1;
        }catch(\Throwable $ex) {
            \DB::rollBack();
            throw $ex;
        }
        return 0;
    }

    public function reject_refund_request(Request $request){
      $refund = RefundRequest::findOrFail($request->refund_id);
      if (Auth::user()->user_type == 'admin' || Auth::user()->user_type == 'staff') {
          $refund->admin_approval = 2;
          $refund->refund_status  = 2;
          $refund->reject_reason  = $request->reject_reason;
      }
      else{
          $refund->seller_approval = 2;
          $refund->reject_reason  = $request->reject_reason;
      }
      
      if ($refund->save()) {
          flash(translate('Refund request rejected successfully.'))->success();
          return back();
      }
      else {
          return back();
      }
    }

    /**
     * Show the form for creating a new resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function refund_request_send_page($id)
    {
        $order_detail = OrderDetail::findOrFail($id);
        if ($order_detail->product != null && $order_detail->product->refundable == 1) {
            return view('refund_request.frontend.refund_request.create', compact('order_detail'));
        }
        else {
            return back();
        }
    }

    /**
     * Show the form for view the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    //Shows the refund reason
    public function reason_view($id)
    {
        $refund = RefundRequest::findOrFail($id);
        if (Auth::user()->user_type == 'admin' || Auth::user()->user_type == 'staff') {
            if ($refund->orderDetail != null) {
                $refund->admin_seen = 1;
                $refund->save();
                return view('refund_request.reason', compact('refund'));
            }
        }
        else {
            return view('refund_request.frontend.refund_request.reason', compact('refund'));
        }
    }

    public function reject_reason_view($id)
    {
        $refund = RefundRequest::findOrFail($id);
        return $refund->reject_reason;
    }

}
